using FileManager.Models;
using FileManager.Services;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Forms = System.Windows.Forms;
using MessageBox = System.Windows.MessageBox;
using MessageBoxButton = System.Windows.MessageBoxButton;
using MessageBoxImage = System.Windows.MessageBoxImage;

namespace FileManager.ViewModels
{
    public class ExportFilesViewModel : BaseViewModel
    {
        private readonly FileExportService _fileExportService;
        private readonly List<FileItem> _filesToExport;
        private CancellationTokenSource _cancellationTokenSource;

        public ExportFilesViewModel(FileExportService fileExportService, List<FileItem> filesToExport)
        {
            _fileExportService = fileExportService;
            _filesToExport = filesToExport;

            ExportCommand = new RelayCommand(async (p) => await ExportFilesAsync());
            CancelCommand = new RelayCommand((p) => CancelExport());
            CloseCommand = new RelayCommand((p) => RequestClose?.Invoke(this, EventArgs.Empty));
            BrowseDirectoryCommand = new RelayCommand((p) => BrowseExportDirectory());

            ExportDirectory = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                "WeChatFileManager_Exports",
                DateTime.Now.ToString("yyyyMMdd_HHmmss"));

            ExportInfoText = $"准备导出 {_filesToExport.Count} 个文件";
            CanExport = true;
        }

        #region 属性

        private string _exportDirectory;
        public string ExportDirectory
        {
            get => _exportDirectory;
            set => SetProperty(ref _exportDirectory, value);
        }

        private bool _decryptDatFiles = true;
        public bool DecryptDatFiles
        {
            get => _decryptDatFiles;
            set => SetProperty(ref _decryptDatFiles, value);
        }

        private bool _preserveDirectoryStructure;
        public bool PreserveDirectoryStructure
        {
            get => _preserveDirectoryStructure;
            set => SetProperty(ref _preserveDirectoryStructure, value);
        }

        private string _exportInfoText;
        public string ExportInfoText
        {
            get => _exportInfoText;
            set => SetProperty(ref _exportInfoText, value);
        }

        private string _progressText;
        public string ProgressText
        {
            get => _progressText;
            set => SetProperty(ref _progressText, value);
        }

        private double _progress;
        public double Progress
        {
            get => _progress;
            set => SetProperty(ref _progress, value);
        }

        private string _resultText;
        public string ResultText
        {
            get => _resultText;
            set => SetProperty(ref _resultText, value);
        }

        private bool _isExporting;
        public bool IsExporting
        {
            get => _isExporting;
            set => SetProperty(ref _isExporting, value);
        }

        private bool _isCompleted;
        public bool IsCompleted
        {
            get => _isCompleted;
            set => SetProperty(ref _isCompleted, value);
        }

        private bool _canExport;
        public bool CanExport
        {
            get => _canExport;
            set => SetProperty(ref _canExport, value);
        }

        private bool _canCancel;
        public bool CanCancel
        {
            get => _canCancel;
            set => SetProperty(ref _canCancel, value);
        }

        #endregion

        #region 命令

        public ICommand ExportCommand { get; }
        public ICommand CancelCommand { get; }
        public ICommand CloseCommand { get; }
        public ICommand BrowseDirectoryCommand { get; }

        #endregion

        #region 事件

        public event EventHandler RequestClose;

        #endregion

        #region 方法

        private async Task ExportFilesAsync()
        {
            if (string.IsNullOrWhiteSpace(ExportDirectory))
            {
                MessageBox.Show("请选择导出目录", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            try
            {
                _cancellationTokenSource = new CancellationTokenSource();
                IsExporting = true;
                IsCompleted = false;
                CanExport = false;
                CanCancel = true;

                Progress = 0;
                ProgressText = "准备导出...";

                int successCount = await _fileExportService.ExportFilesAsync(
                    _filesToExport,
                    ExportDirectory,
                    DecryptDatFiles,
                    PreserveDirectoryStructure,
                    (current, total, fileName) =>
                    {
                        Progress = current * 100.0 / total;
                        ProgressText = $"正在导出 {current}/{total}: {fileName}";
                    });

                ResultText = $"导出完成。成功导出 {successCount}/{_filesToExport.Count} 个文件到:\n{ExportDirectory}";
                IsCompleted = true;
                CanCancel = false;
            }
            catch (OperationCanceledException)
            {
                ResultText = "导出已取消";
                IsCompleted = true;
            }
            catch (Exception ex)
            {
                ResultText = $"导出过程中出错: {ex.Message}";
                IsCompleted = true;
            }
            finally
            {
                IsExporting = false;
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = null;
            }
        }

        private void CancelExport()
        {
            _cancellationTokenSource?.Cancel();
            CanCancel = false;
            ProgressText = "正在取消...";
        }

        private void BrowseExportDirectory()
        {
            var dialog = new System.Windows.Forms.FolderBrowserDialog
            {
                Description = "选择导出目录",
                SelectedPath = ExportDirectory,
                ShowNewFolderButton = true
            };

            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                ExportDirectory = dialog.SelectedPath;
            }
        }

        #endregion
    }
}